function MyPromise(fn) {
    // 参数必须是一个函数
    if (typeof fn !== 'function') {
        throw Error(`Promise resolver ${fn} is not a function`);
    }

    var _self = this;
    this.status = 'pending'; // 当前promise状态
    this.data = null;        // 回掉函数返回值储存
    this.resolvedArr = [];   // 注册的成功的回掉函数
    this.rejectedArr = [];   // 注册的失败的回掉韩式

    function resolved(data) {
        if (_self.status === 'pending') {
            _self.status = 'resolved';
            _self.data = data;
            _self.resolvedArr.forEach(function (item) {
                item();
            });
        }
    }

    function rejected(err) {
        if (_self.status === 'pending') {
            _self.status = 'rejected';
            _self.data = err;
            _self.rejectedArr.forEach(function (item) {
                item();
            });
        }
    }

    try {
        fn(resolved, rejected);
    } catch (e) {
        rejected(e);
    }
}
// 这个函数用来处理上个then返回值当返回值是promise对象时我们就用我们返回的promise的res，rej来改变peomise状态
// 品， 细品吧  我说不太明白
function handleResolve(nextProVal, res, rej) {
    if (nextProVal instanceof MyPromise) {
        nextProVal.then(function (val) {
            res(val)
        }, function (err) {
            rej(err)
        })
    } else {
        res(nextProVal)
    }
}

MyPromise.prototype.then = function (onResolved, onRejected) {
    var _self = this;
    if (!onResolved) {
        onResolved = function (res) {
            return res
        }
    }
    if (!onRejected) {
        onRejected = function (err) {
            throw new Error(err)
        }
    }
    var promise = new MyPromise(function (res, rej) {
        if (_self.status === 'resolved') {
            setTimeout(function () {
                try {
                    var nextProVal = onResolved(_self.data);
                    handleResolve(nextProVal, res, rej)
                } catch (e) {
                    rej(e)
                }
            });
        }
        if (_self.status === 'rejected') {
            setTimeout(function () {
                try {
                    var nextProVal = onRejected(_self.data);
                    handleResolve(nextProVal, res, rej)
                } catch (e) {
                    rej(e)
                }
            });
        }
        if (_self.status === 'pending') {
            _self.resolvedArr.push(function () {
                setTimeout(function () {
                    try {
                        var nextProVal = onResolved(_self.data);
                        handleResolve(nextProVal, res, rej)
                    } catch (e) {
                        rej(e)
                    }
                });
            });
            _self.rejectedArr.push(function () {
                setTimeout(function () {
                    try {
                        var nextProVal = onRejected(_self.data);
                        handleResolve(nextProVal, res, rej)
                    } catch (e) {
                        rej(e)
                    }
                });
            });
        }
    });
    return promise
}

MyPromise.all = function (promiseList) {
    return new MyPromise(function (res, rej) {
        let resolveArr = [];
        promiseList.forEach((item, index) => {
            item.then(data => {
                resolveArr.push(data);
                if (promiseList.length === resolveArr.length) {
                    res(resolveArr);
                }
            }, err => {
                rej(err);
            });
        });
    });
}

MyPromise.race = function (promiseList) {
    return new MyPromise(function (res, rej) {
        promiseList.forEach(function(item, index) {
            item.then(function(data) {
                res(data)
            }, function(err) {
                rej(err)
            });
        });
    });
}